package com.intelligent.system.auth.uitls;

import com.intelligent.system.auth.dto.UserDTO;
import com.intelligent.system.auth.service.IUserService;

import com.intelligent.system.auth.dto.StaffInfoDTO;

import com.intelligent.system.common.response.ResultDO;
import com.intelligent.system.common.utils.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * OAuth2用户信息工具类
 * 用于从Redis中读取用户信息、机构信息和token，并同步到数据库
 */
@Slf4j
@Component
public class OAuth2UserInfoUtils {

    @Resource
    private RedisUtils redisUtils;

    @Resource
    private IUserService userService;
    // Redis key prefixes
    private static final String REDIS_USER_PREFIX = "user:";
    private static final String REDIS_TOKEN_PREFIX = "token:";


    /**
     * 获取用户信息
     * 优先从Redis获取，如果不存在则从数据库获取并缓存
     *
     * @param staffId 员工ID
     * @return 用户信息Map，如果不存在返回null
     */
    public Map<Object, Object> getUserInfo(String staffId) {
        try {
            // 先从Redis获取
            String key = REDIS_USER_PREFIX + staffId;
            Map<Object, Object> userInfo = redisUtils.hGetAll(key);
            
            if (userInfo == null || userInfo.isEmpty()) {
                // Redis中不存在，从数据库获取
                ResultDO<UserDTO> res = userService.getUserById(Long.getLong(staffId));
                if (res.getData() != null) {
                    // 转换为Map并缓存到Redis
                    userInfo = convertUserToMap(res.getData());
                    redisUtils.hSetAll(key, userInfo);
                    redisUtils.expire(key, 24, TimeUnit.HOURS);
                }
            }
            
            return userInfo;
        } catch (Exception e) {
            log.error("获取员工ID {} 的用户信息失败", staffId, e);
            return null;
        }
    }

    /**
     * 获取访问令牌
     *
     * @param staffId 员工ID
     * @return 访问令牌，如果不存在返回null
     */
    public String getAccessToken(String staffId) {
        try {
            String key = REDIS_TOKEN_PREFIX + staffId;
            Object token = redisUtils.get(key);
            if (token == null) {
                log.warn("Redis中未找到员工ID {} 的访问令牌", staffId);
                return null;
            }
            return token.toString();
        } catch (Exception e) {
            log.error("从Redis获取员工ID {} 的访问令牌失败", staffId, e);
            return null;
        }
    }

    /**
     * 检查用户信息是否存在
     *
     * @param staffId 员工ID
     * @return 是否存在
     */
    public boolean hasUserInfo(String staffId) {
        try {
            String key = REDIS_USER_PREFIX + staffId;
            return redisUtils.hasKey(key);
        } catch (Exception e) {
            log.error("检查Redis中员工ID {} 的用户信息是否存在时失败", staffId, e);
            return false;
        }
    }

    /**
     * 检查访问令牌是否存在
     *
     * @param staffId 员工ID
     * @return 是否存在
     */
    public boolean hasAccessToken(String staffId) {
        try {
            String key = REDIS_TOKEN_PREFIX + staffId;
            return redisUtils.hasKey(key);
        } catch (Exception e) {
            log.error("检查Redis中员工ID {} 的访问令牌是否存在时失败", staffId, e);
            return false;
        }
    }

    /**
     * 删除用户相关信息
     *
     * @param staffId 员工ID
     * @return 是否删除成功
     */
    public boolean deleteUserInfo(String staffId) {
        try {
            String userKey = REDIS_USER_PREFIX + staffId;
            String tokenKey = REDIS_TOKEN_PREFIX + staffId;
            
            // 删除用户信息和token
            redisUtils.delete(userKey);
            redisUtils.delete(tokenKey);
            
            log.info("已成功从Redis中删除员工ID {} 的用户信息", staffId);
            return true;
        } catch (Exception e) {
            log.error("从Redis中删除员工ID {} 的用户信息失败", staffId, e);
            return false;
        }
    }



    /**
     * 更新用户信息
     */
    public boolean updateUserInfo(String staffId, Map<Object, Object> userInfo) {
        try {
            // 更新数据库
            StaffInfoDTO staffInfoDTO = new StaffInfoDTO();
            staffInfoDTO.setStaffId(staffId);
            staffInfoDTO.setStatus((Integer) userInfo.get("status"));
            staffInfoDTO.setUsername((String) userInfo.get("username"));
            UserDTO userDTO = userService.createOrUpdateUser(staffInfoDTO);
            if (userDTO == null) {
                return false;
            }
            // 更新Redis缓存
            String userKey = REDIS_USER_PREFIX + staffId;
            Map<Object, Object> updatedInfo = convertUserToMap(userDTO);
            redisUtils.hSetAll(userKey, updatedInfo);
            redisUtils.expire(userKey, 24, TimeUnit.HOURS);
            return true;
        } catch (Exception e) {
            log.error("更新员工ID {} 的用户信息时发生错误", staffId, e);
            return false;
        }
    }

    /**
     * 将SysUser对象转换为Map
     */
    private Map<Object, Object> convertUserToMap(UserDTO user) {
        Map<Object, Object> map = new HashMap<>();
        map.put("staffId", user.getUserId());
        map.put("username", user.getLoginName());
        map.put("mobile", user.getPhonenumber());
        map.put("email", user.getEmail());
        map.put("status", user.getStatus());
        return map;
    }

    /**
     * 将Map转换为StaffInfoDTO对象
     */
    private StaffInfoDTO convertMapToStaffInfoDTO(Map<Object, Object> map) {
        StaffInfoDTO staffInfoDTO = new StaffInfoDTO();
        staffInfoDTO.setStaffId((String) map.get("staffId"));
        staffInfoDTO.setStatus((Integer) map.get("status"));
        staffInfoDTO.setUsername((String) map.get("username"));
        return staffInfoDTO;
    }
} 